﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using SerienNewsReader.Model;
using System.Net;
using System.Xml.Linq;

namespace SerienNewsReader.ViewModel
{
    public class Series : INotifyPropertyChanged, IDisposable
    {
        #region INotifyPropertyChanged Members

        /// <summary>
        /// Event that indicates that a property changed his value
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Eventhandler that is triggerd when a property changes his value
        /// </summary>
        /// <param name="propertyName">name of the property</param>
        protected virtual void OnPropertyChanged(String propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        /// <summary>
        /// private list of all series
        /// </summary>
        private ObservableCollection<RSSFeed> serien = default(ObservableCollection<RSSFeed>);

        /// <summary>
        /// private list of all tv movies
        /// </summary>
        private ObservableCollection<RSSFeed> tvMovies = default(ObservableCollection<RSSFeed>);

        /// <summary>
        /// Collection containing all series
        /// </summary>
        public ObservableCollection<RSSFeed> Serien
        {
            get { return this.serien; }
            set
            {
                if (value != this.serien)
                {
                    this.serien = value;
                    OnPropertyChanged("Serien"); 
                }
            }
        }

        /// <summary>
        /// Collection containing all tv movies
        /// </summary>
        public ObservableCollection<RSSFeed> TvMovies
        {
            get
            {
                return this.tvMovies;
            }

            set
            {
                if (value != this.tvMovies)
                {
                    this.tvMovies = value;
                    this.OnPropertyChanged("TvMovies");
                }
            }
        }

        /// <summary>
        /// Delegate for a completed download
        /// </summary>
        /// <param name="sender">Object that sends the event</param>
        /// <param name="e">Eventarguments</param>
        public delegate void DownloadCompletedDelegate(object sender, EventArgs e);

        /// <summary>
        /// Occures when a download is completed
        /// </summary>
        public event DownloadCompletedDelegate DownloadCompleted;

        /// <summary>
        /// Initialises a new instance of Series class.
        /// Stating the download of the rss feed.
        /// </summary>
        public Series()
        {
            this.Serien = new ObservableCollection<RSSFeed>();
            this.TvMovies = new ObservableCollection<RSSFeed>();
            this.LoadFeedsAsync();
        }

        /// <summary>
        /// Loads all the RSSFeeds asyncron
        /// </summary>
        private void LoadFeedsAsync()
        {
            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            client.DownloadStringAsync(new Uri("http://serienjunkies.org/xml/feeds/episoden.xml", UriKind.Absolute));
        }

        /// <summary>
        /// Parse the downloaded RSSFeeds and fill the ObservableCollection
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            ((WebClient)sender).DownloadStringCompleted -= client_DownloadStringCompleted;

            if (e.Error == null && e.Cancelled == false)
            {
                this.Serien.Clear();

                XElement xelement = XElement.Parse(e.Result);

                var items = xelement.Descendants(XName.Get("item"));

                foreach (var item in items)
                {
                    var title = item.Descendants(XName.Get("title")).SingleOrDefault();
                    string[] spliter = ((String)title.Value).Split(']');
                    String serienLanguage = spliter[0].Remove(0, 1);
                    String serienTitle = spliter[1].Replace('.', ' ').Trim();
                    var link = item.Descendants(XName.Get("link")).SingleOrDefault();
                    RSSFeed feed = new RSSFeed(serienTitle, serienLanguage, new Uri(link.Value));

                    if (feed.Language.ToUpper().Equals("TV-FILM"))
                    {
                        this.TvMovies.Add(feed);
                    }
                    else
                    {
                        this.Serien.Add(feed);
                    }
                    //this.Serien.Add(new RSSFeed(serienTitle, serienLanguage, new Uri(link.Value)));
                }
            }

            this.TvMovies.OrderBy(x => x.Title);
            this.Serien.OrderBy(x => x.Title);
            if (this.DownloadCompleted != null)
            {
                this.DownloadCompleted(this, EventArgs.Empty);
            }
        }

        public void Dispose()
        {
            this.serien = null;
            this.tvMovies = null;
        }
    }
}
